package org.smarthings.things.automation.engine;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.smarthings.things.commons.Paginatable;
import org.smarthings.things.commons.Paginator;
import org.smarthings.things.management.Thing;
import org.smarthings.things.management.ThingCollection;

public class ThingCollectionFacade implements Paginatable<ThingFacade>, Iterable<ThingFacade> {

	private ThingCollection collection;

	public ThingCollectionFacade(ThingCollection collection) {
		this.collection = collection;
	}

	@Override
	public Paginator<ThingFacade> paginator(int offset, int limit) {
		return new PaginatorFacade(collection.paginator(offset, limit));
	}

	@Override
	public Iterator<ThingFacade> iterator() {
		return new IteratorFacade(collection.iterator());
	}
	
	class PaginatorFacade implements Paginator<ThingFacade> {
		
		Paginator<Thing> paginator;
		
		PaginatorFacade(Paginator<Thing> paginator) {
			this.paginator = paginator;
		}

		@Override
		public List<ThingFacade> next() {
			transform(paginator.next());
			
			return null;
		}

		@Override
		public List<ThingFacade> previous() {
			return transform(paginator.previous());
		}

		@Override
		public List<ThingFacade> first() {
			return transform(paginator.first());
		}

		@Override
		public List<ThingFacade> last() {
			return transform(paginator.last());
		}
		
	}
	
	class IteratorFacade implements Iterator<ThingFacade> {
		
		Iterator<Thing> iterator;
		
		IteratorFacade(Iterator<Thing> iterator) {
			this.iterator = iterator;
		}

		@Override
		public boolean hasNext() {
			return iterator.hasNext();
		}

		@Override
		public ThingFacade next() {
			return new ThingFacade(iterator.next());
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
		
	}
	private static List<ThingFacade> transform(List<Thing> list) {
		if (list == null) {
			return null;
		}
		List<ThingFacade> result = new ArrayList<ThingFacade>(list.size());
		for (Thing thing : list) {
			result.add(new ThingFacade(thing));
		}
		return result;
	}

}
